import math
import uuid

from django.core.validators import RegexValidator
from django.http import JsonResponse
from rest_framework import exceptions
from rest_framework import serializers
from rest_framework.negotiation import DefaultContentNegotiation
from rest_framework.parsers import JSONParser, FormParser
from rest_framework.response import Response
# from rest_framework.versioning import QueryParameterVersioning
# from rest_framework.versioning import AcceptHeaderVersioning
from rest_framework.versioning import URLPathVersioning
from rest_framework.views import APIView

from api.models import User, Depart, UserInfo
from ext import http_code
from ext.throttle import IpThrottle, UserThrottle


# from ext.permission import UserPermission


# Create your views here.
def home(request):
    return JsonResponse({"status": "success"})


class HomeView(APIView):
    authentication_classes = []
    permission_classes = []

    def get(self, request):
        return Response({"status": "success"})


class LoginView(APIView):
    authentication_classes = []
    permission_classes = []
    throttle_classes = [IpThrottle]

    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user_object = User.objects.filter(username=username, password=password).first()
        if not user_object:
            return Response({"code": http_code.ERROR_LOGIN, "message": "用户名或密码错误"})
        token = str(uuid.uuid1())
        user_object.token = token
        user_object.save()
        return Response({"code": http_code.SUCCESS, "message": "登录成功", "data": {"token": token}})


class OrderView(APIView):
    throttle_classes = [UserThrottle, ]

    def get(self, request):
        print(request.user)
        print(request.auth)
        return Response({"status": "success"})

    def throttled(self, request, wait):
        if wait is not None:
            wait = math.ceil(wait)
            print("wait", wait)
        raise exceptions.Throttled(wait=wait, detail="您的请求过于频繁，请稍后再试！", code=http_code.ERROR_THROTTLE)

    # 修改权限的校验规则，只要有一个满足就成功(默认，只要有一个不满足就不行)
    def check_permissions(self, request):
        no_permissions = []
        for permission in self.get_permissions():
            if permission.has_permission(request, self):
                return
            else:
                no_permissions.append(permission)
        else:
            self.permission_denied(
                request,
                message=getattr(no_permissions[0], 'message', None),
                code=getattr(no_permissions[0], 'code', None)
            )


class UserView(APIView):
    # permission_classes = [UserPermission, ]

    def get(self, request):
        return Response(
            {"code": http_code.SUCCESS, "message": "请求成功", "data": {"user": {
                "username": request.user.username,
                "password": request.user.password,
                "id": request.user.id,
            }, "token": request.auth}})


class InfoView(APIView):
    # versioning_class = QueryParameterVersioning
    # versioning_class = AcceptHeaderVersioning
    versioning_class = URLPathVersioning

    def get(self, request, *args, **kwargs):
        print(request.version)
        return Response({"code": http_code.SUCCESS, "message": "请求成功"})


class ParseView(APIView):
    parser_classes = [JSONParser, FormParser]
    content_negotiation_class = DefaultContentNegotiation

    def post(self, request):
        print(request.data, type(request.data))
        return Response({"code": http_code.SUCCESS, "message": "请求成功"})


# class DepartSerializers(serializers.Serializer):
#     title = serializers.CharField()
#     count = serializers.IntegerField()

class DepartSerializers(serializers.ModelSerializer):
    # name = serializers.CharField(required=True, max_length=32, min_length=6)
    # desc = serializers.CharField(validators=[RegexValidator(regex=r'^[a-zA-Z]+$',message="正则校验失败")])

    class Meta:
        model = Depart
        # fields = "__all__"  # 序列化所有的字段
        fields = ['id', 'title', 'order', 'count', ]  # 序列化指定字段
        extra_kwargs = {
            'id': {'read_only': True},
            'title': {'required': True, 'max_length': 32, 'min_length': 1},
            'order': {'required': True, 'write_only': True},
            'count': {'required': True, 'validators': [RegexValidator(regex=r'\d+', message="人数错误")],
                      'write_only': True},
        }

    def validate(self, attrs):
        # depart_object = Depart.objects.filter(title=attrs.get('title'))
        # if depart_object.exists():
        #     raise serializers.ValidationError(f"{attrs.get('title')}已经存在了")
        # else:
        #     return attrs
        return attrs


class DepartView(APIView):
    versioning_class = URLPathVersioning

    def get(self, request, *args, **kwargs):
        # 单个
        # depart_object = Depart.objects.all().first()
        # ser = DepartSerializers(instance=depart_object)
        # 多个
        depart_object = Depart.objects.all()
        ser = DepartSerializers(instance=depart_object, many=True)
        print(ser.data)
        return Response({"code": http_code.SUCCESS, "message": "请求成功", "data": ser.data})

    def post(self, request, *args, **kwargs):
        print(request.data)
        # title, order, count = request.data
        # ser = DepartSerializers(data=request.data)
        # ser.is_valid(raise_exception=True)
        # if ser.is_valid():
        #     message = ser.validated_data
        # else:
        #     message = ser.errors

        # depart_object = Depart.objects.filter(title=request.data.get('title'))
        # if depart_object.exists():
        #     return Response(
        #         {"code": http_code.ERROR_DEPART_EXIST, "message": f"{request.data.get('title')}已经存在了"})
        # else:
        #     Depart.objects.create(title=request.data.get('title'), order=request.data.get('order'),
        #                           count=request.data.get('count')).save()
        #     return Response({"code": http_code.SUCCESS, "message": f"{request.data.get("title")}新增成功"})

        ser = DepartSerializers(data=request.data)
        if ser.is_valid():
            depart_object = Depart.objects.filter(title=request.data.get('title'))
            if depart_object.exists():
                return Response(
                    {"code": http_code.ERROR_DEPART_EXIST, "message": f"{request.data.get('title')}已经存在了"})
            else:
                # instance = Depart.objects.create(title=request.data.get('title'), order=request.data.get('order'),
                #                                  count=request.data.get('count')).save()

                # Depart.objects.create(**ser.data).save()
                ser.save()
                # resp = DepartSerializers(instance=instance)
                # print("resp", resp, resp.data)
                return Response({"code": http_code.SUCCESS, "message": f"新增成功", "data": ser.data})
        else:
            message = ser.errors
            return Response(
                {"code": http_code.ERROR, "message": f"{message}"})


class UserInfoSerializer(serializers.ModelSerializer):
    # 定制化指定字段
    # genderName = serializers.IntegerField(source="gender", read_only=True)
    genderName = serializers.CharField(source="get_gender_display", read_only=True)
    # 内部序列化的时候，for循环遍历每一个userInfo对象。这个source就相当于  对象.depart.title
    departName = serializers.CharField(source="depart.title", read_only=True)
    createTime = serializers.DateTimeField(source="ctime", format="%Y-%m-%d %H:%M:%S", read_only=True)
    utime = serializers.DateTimeField(format="%Y-%m-%d", read_only=True)

    # 自定义属性
    xxx = serializers.SerializerMethodField()

    class Meta:
        model = UserInfo
        fields = ["name", "age", "gender", "genderName", "depart", "departName", "ctime", "createTime", "utime", "xxx"]

    def get_xxx(self, obj):
        return obj.name


class UserInfoView(APIView):
    versioning_class = URLPathVersioning

    def get(self, request, *args, **kwargs):
        user_info_object = UserInfo.objects.all()
        ser = UserInfoSerializer(instance=user_info_object, many=True)
        print(ser.data)
        return Response({"code": http_code.SUCCESS, "message": "请求成功", "data": ser.data})
